﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DataAccessLayer.Security;
using Common;
using System.Data.Objects;
using System.Data.Common;

namespace DataAccessLayer.DAL
{
    public class UserDAL
    {
        /// <summary>
        /// Kiem tra dang nhap
        /// </summary>
        /// <param name="username">Username of user store in DB</param>
        /// <param name="password">Password of user store in DB</param>
        /// <returns></returns>
        public static bool ValidateUserLogin(string username, string password)
        {
            using (var context = new ReverseAuctionEntities())
            {
                password = EncryptDataAccessLayer.GenerateMd5Hash(password);
                int activeStatus = (int)Common.UserStatus.Active;
                var user = context.Users.SingleOrDefault(u => u.Username == username && u.Password == password && u.Status == activeStatus);
                return user != null;
            }
        }

        /// <summary>
        /// Lay thong tin cua mot user bang username
        /// </summary>
        /// <param name="username">Username of user store in DB</param>
        /// <returns>Appropriate user if exists, NULL if not.</returns>
        public static User GetUserByUsername(string username)
        {
            using (var context = new ReverseAuctionEntities())
            {
                return context.Users.SingleOrDefault(u => u.Username == username);
            }
        }

        public static List<User> GetUserByRole(int role, int status)
        {
            List<User> list = null;
            using (var context = new ReverseAuctionEntities())
            {
                list = context.Users.Where(u => u.RoleID == role && u.Status==status).ToList();
            }
            return list;
        }

        /// <summary>
        /// Them moi mot user
        /// </summary>
        /// <param name="user">User to add.</param>
        public static void AddUser(User user)
        {
            using (var context = new ReverseAuctionEntities())
            {
                context.Users.AddObject(user);
                context.SaveChanges();
            }
        }

        /// <summary>
        /// Cap nhat thong tin mot user
        /// </summary>
        /// <param name="user">User to update</param>
        public static void UpdateUser(User user)
        {
            using (var context = new ReverseAuctionEntities())
            {
                context.Users.Attach(user);
                context.ObjectStateManager.ChangeObjectState(user, System.Data.EntityState.Modified);
                context.SaveChanges();
            }
        }

        public static void UpdateStatusUser(int userID, int status)
        {
            using (var context = new ReverseAuctionEntities())
            {
                var result = context.Users.SingleOrDefault(u => u.ID == userID);
                if (result != null)
                {
                    result.Status = status;
                    context.SaveChanges();
                }
            }
        }

        /// <summary>
        /// Xoa User
        /// Chu y: Method nay chi dung de Demo cach xoa Entity trong Entity Framework (EF).
        /// Trong Project nay, khi can xoa mot doi tuong ta phai cap nhat gia tri Status tuong ung.
        /// </summary>  
        /// <param name="userID"></param>
        public static void DeleteUser(int userID)
        {
            using (var context = new ReverseAuctionEntities())
            {
                User user = context.Users.SingleOrDefault(u => u.ID == userID);
                if (user != null)
                {
                    context.Users.DeleteObject(user);
                    context.SaveChanges();
                }
            }
        }

        public static void CreateUser(User user)
        {
            using (var context = new ReverseAuctionEntities())
            {
                user.Password = EncryptDataAccessLayer.GenerateMd5Hash(user.Password);

                context.Users.AddObject(user);
                context.SaveChanges();
            }
        }

        public static User GetUser(int userID)
        {
            using (var context = new ReverseAuctionEntities())
            {
                return context.Users.Include("UserReference").SingleOrDefault(u => u.ID == userID);
            }
        }

        public static User FindUserByActiveCode(string code)
        {
            using (var context = new ReverseAuctionEntities())
            {
                return context.Users.FirstOrDefault(u => u.ActiveCode == code);
            }
        }

        public static void ActiveUserByCode(string code)
        {
            using (var context = new ReverseAuctionEntities())
            {
                int activeStatus = (int)UserStatus.Active;
                context.Users.Where(u => u.ActiveCode == code).ToList().ForEach(u =>
                {
                    u.Status = activeStatus;
                });
                context.SaveChanges();
            }
        }


        public static User GetUserByEmail(string email)
        {
            using (var context = new ReverseAuctionEntities())
            {
                return context.Users.SingleOrDefault(u => u.Email == email);
            }
        }

        public static void UpdatePassword(string username, string newPassword)
        {
            using (var context = new ReverseAuctionEntities())
            {
                newPassword = EncryptDataAccessLayer.GenerateMd5Hash(newPassword);

                User origUser = context.Users.SingleOrDefault(u => u.Username == username);
                origUser.Password = newPassword;

                context.SaveChanges();
            }
        }

        /// <summary>
        /// Lay Payment Details cua user bang UserID
        /// </summary>
        /// <param name="userID">UserID of user store in DB</param>
        /// <returns></returns>
        public static PaymentDetail GetPaymentDetailByID(int id)
        {
            using (var context = new ReverseAuctionEntities())
            {
                return context.PaymentDetails.SingleOrDefault(u => u.UserID == id);
            }
        }


        /// <summary>
        /// Lay id cua mot user bang username
        /// </summary>
        /// <param name="username">Username of user store in DB</param>
        /// <returns>Appropriate user if exists, NULL if not.</returns>
        public static int GetUserIDByUsername(string username)
        {
            using (var context = new ReverseAuctionEntities())
            {
                return context.Users.SingleOrDefault(u => u.Username == username).ID;
            }
        }

        /// <summary>
        /// Cap nhat Payment Details cua user bang UserID
        /// </summary>
        /// <param name="PaymentDetails">PaymentDetails of user store in DB</param>
        /// <returns></returns>
        public static bool UpdatePaymentDetail(PaymentDetail pay)
        {
            using (var context = new ReverseAuctionEntities())
            {
                var payment = context.PaymentDetails.SingleOrDefault(u => u.UserID == pay.UserID);
                if (payment == null)
                {
                    //context.ObjectStateManager.ChangeObjectState(pay, System.Data.EntityState.Added);
                    context.PaymentDetails.AddObject(pay);
                }
                else
                {
                    context.PaymentDetails.Detach(payment);
                    context.PaymentDetails.Attach(pay);
                    context.ObjectStateManager.ChangeObjectState(pay, System.Data.EntityState.Modified);
                }
                context.SaveChanges();
                return true;
            }
        }

        /// <summary>
        /// Bookmark auction
        /// </summary>
        /// <param name="FollowAuction">FollowAuction</param>
        /// <returns></returns>
        /// 
        public static User GetAllBookmark(int userID)
        {
            using (var context = new ReverseAuctionEntities())
            {
                return context.Users.Include("FollowAuctions").Include("FollowAuctions.Auction").SingleOrDefault(u => u.ID == userID);
            }
        }
     
        public static FollowAuction GetFollowAuctionByID(int userID, int auctionID)
        {
            using (var context = new ReverseAuctionEntities())
            {
                return context.FollowAuctions.SingleOrDefault(u => u.AuctionID == auctionID && u.SellerID == userID);
            }
        }
        
        public static void AddFollowAuction(FollowAuction follow)
        {
            using (var context = new ReverseAuctionEntities())
            {
                var result = context.FollowAuctions.SingleOrDefault(u => u.SellerID == follow.SellerID 
                    && u.AuctionID == follow.AuctionID);
                if (result == null)
                {
                    context.FollowAuctions.AddObject(follow);
                    context.SaveChanges();
                }
            }
        }

        /// <summary>
        /// Feedback
        /// </summary>

        public static AuctionTransaction GetFeedbackByAuctionID(int auctionID)
        {
            using (var context = new ReverseAuctionEntities())
            {
                return context.AuctionTransactions.Include("Auction").Include("TransactionFeedbacks")
                    .Include("TransactionFeedbacks.User").Include("TransactionFeedbacks.User1")
                    .SingleOrDefault(u => u.AuctionID == auctionID);
            }
        }

        public static void AddFeedback(TransactionFeedback feedback)
        {
            using (var context = new ReverseAuctionEntities())
            {
                context.TransactionFeedbacks.AddObject(feedback);
                context.SaveChanges();
            }
        }

        public static List<Auction> GetCreateAucByBuyerID(int buyerID)
        {
            List<Auction> list = new List<Auction>();
            using (var context = new ReverseAuctionEntities())
            {
                var result = context.Auctions.Where(u => u.CreateByUserID == buyerID && u.Status != (int)AuctionStatus.Delete)
                                                .OrderBy(u=>u.Status);
                foreach (var item in result)
                {
                    list.Add(item);
                }
            }
            return list;
        }

        public static List<AuctionTransaction> GetEndAucByBuyerID(int userID)
        {
            using (var context = new ReverseAuctionEntities())
            {
                List<AuctionTransaction> list = new List<AuctionTransaction>();
                var result = context.Users.Include("Auctions").Include("Auctions.AuctionTransaction")
                    .Include("Auctions.AuctionTransaction.User").SingleOrDefault(u => u.ID == userID);
                foreach (var auc in result.Auctions)
                {
                    if (auc.AuctionTransaction != null)
                    {
                        list.Add(auc.AuctionTransaction);
                    }
                }
                return list;
            }
        }

        public static void BuyGoldMember(int userID, int day)
        {
            using (var context = new ReverseAuctionEntities())
            {
                var result = context.Users.SingleOrDefault(u => u.ID == userID);
                result.GoldMemberDueTo = result.GoldMemberDueTo.Value.AddDays(day);
                context.SaveChanges();
            }
        }
    }
}
